package com.zhuangjie.mvc.helper.GeoHelper.process;

import com.zhuangjie.mvc.helper.GeoHelper.CoordinateTransferUtils;
import com.zhuangjie.mvc.helper.GeoHelper.GeoCoordinates;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.Objects;

@Aspect
@Component
public class GeoConvertAopHandler {
    /**
     * 拦截标有@GeoConvert注解的参数方法，对注解对应的参数值必须是GeoCoordinates类型，然后调用geo转换方法tryConvert
     * 如果参数类型不满足则跳过
     * @param pjp pjp
     * @return {@link Object}
     * @throws Throwable 可丢弃
     */
    @Around("execution(* *(.., @com.zhuangjie.mvc.helper.GeoHelper.process.GeoConvert (*), ..))")
    public Object validate(ProceedingJoinPoint pjp) throws Throwable {
        // Get method signature
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        // Get method
        Method method = signature.getMethod();
        // Get parameter annotations
        Annotation[][] annotations = method.getParameterAnnotations();
        // Loop through all parameters
        for(int i = 0; i < annotations.length; i++) {
            // Check annotations of parameter
            for(Annotation annotation : annotations[i]) {
                if(annotation.annotationType().equals(GeoConvert.class) ) {
                    // Get actual parameter value
                    Object value = pjp.getArgs()[i];
                    // Process parameter here
                    if (value instanceof GeoCoordinates) {
                        GeoConvert convertAnnotation = ((GeoConvert)annotation);
                        GeoCoordinates geoCoordinates = (GeoCoordinates) value;
                        // 目标坐标类型
                        String targetCoordType = convertAnnotation.targetType().getCode();
                        String sourceCoordType = geoCoordinates.getCoordinateType();
                        if (Objects.equals(targetCoordType,sourceCoordType)) break;
                        double[] doubles = CoordinateTransferUtils.coordConvert(targetCoordType,sourceCoordType,geoCoordinates.getLongitude(), geoCoordinates.getLatitude());
                        geoCoordinates.setLongitude(doubles[0]);
                        geoCoordinates.setLatitude(doubles[1]);
                        geoCoordinates.setCoordinateType(convertAnnotation.targetType().getCode());
                    }
                }
            }
        }
        return pjp.proceed();
    }
}
